package pro.wy.dynamicproxy.test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import pro.wy.dynamicproxy.handler.WorkHandler;
import pro.wy.dynamicproxy.impl.Teacher;
import pro.wy.dynamicproxy.interfaces.People;

/**
 * <p>
 * Description:动态代理测试类
 * </p>
 * <p>
 * Copyright: Copyright (c) 2018
 * </p>
 * 
 * @author 王跃 2019年8月29日
 */
public class ProxyTest2 {

	public static void main(String[] args) {
		// 要代理的真实对象
		People people = new Teacher();
		// 代理对象的调用处理程序，我们将要代理的真实对象传入代理对象的调用处理的构造函数中，最终代理对象的调用处理程序会调用真实对象的方法
		InvocationHandler handler = new WorkHandler(people);
		/**
		 * 通过Proxy类的newProxyInstance方法创建代理对象，我们来看下方法中的参数
		 * 第一个参数：people.getClass().getClassLoader()，使用handler对象的classloader对象来加载我们的代理对象
		 * 第二个参数：people.getClass().getInterfaces()，这里为代理类提供的接口是真实对象实现的接口，这样代理对象就能像真实对象一样调用接口中的所有方法
		 * 第三个参数：handler，我们将代理对象关联到上面的InvocationHandler对象上
		 */
		People subject = (People) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
				people.getClass().getInterfaces(), handler);
		// System.out.println(proxy.toString());
		// 这里可以通过运行结果证明subject是Proxy的一个实例，这个实例实现了Subject接口
		// 测试它左边的对象是否是它右边的类的实例
		System.out.println(subject instanceof Proxy);
		// 这里可以看出subject的Class类是$Proxy0,这个$Proxy0类继承了Proxy，实现了Subject接口
		System.out.println("subject的Class类是：" + subject.getClass().toString());
		System.out.print("subject中的属性有：");

		Field[] field = subject.getClass().getDeclaredFields();
		for (Field f : field) {
			System.out.print(f.getName() + ", ");
		}

		System.out.print("\n" + "subject中的方法有：");

		Method[] method = subject.getClass().getDeclaredMethods();

		for (Method m : method) {
			System.out.print(m.getName() + ", ");
		}

		System.out.println("\n" + "subject的父类是：" + subject.getClass().getSuperclass());

		System.out.print("\n" + "subject实现的接口是：");

		Class<?>[] interfaces = subject.getClass().getInterfaces();

		for (Class<?> i : interfaces) {
			System.out.print(i.getName() + ", ");
		}
		System.out.println("\n\n" + "运行结果为：");
		System.out.println(subject.work("王老师"));
	}
}
